package com.example.blogdemo.controller;

import com.example.blogdemo.entity.*;
import com.example.blogdemo.repository.ArticleTagRepository;
import com.example.blogdemo.service.ArticleService;
import com.example.blogdemo.service.CommentService;
import com.example.blogdemo.service.JedisService;
import com.example.blogdemo.service.LikeService;
import com.example.blogdemo.service.TagService;
import com.example.blogdemo.service.UserService;
import com.example.blogdemo.util.JblogUtil;
import com.example.blogdemo.util.RedisKeyUntil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import javax.swing.text.View;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

/**
 * @author ：Anitaxiaofeng
 * @description：
 * @create 2017-12-15
 **/
@Controller
@Slf4j
public class ArticleController {

    @Autowired
    private ArticleService articleService;

    @Autowired
    private TagService tagService;

    @Autowired
    private ArticleTagRepository articleTagRepository;

    @Autowired
    private JedisService jedisService;

    @Autowired
    private HostHolder hostHolder;

    @Autowired
    private LikeService likeService;

    @Autowired
    private CommentService commentService;

    @Autowired
    private UserService userService;





    @RequestMapping("/page/{pageId}")
    public String article(Model model,@PathVariable("pageId")int pageId){
        List<ViewObject> vos = new ArrayList<>();
        List<Article> articles = articleService.getLatestArticles(pageId-1,4);
        for(Article article:articles){
            ViewObject vo = new ViewObject();
            List<Tag> tags = tagService.getTagByArticleId(article.getId());
            String clickCount = jedisService.get(RedisKeyUntil.getClickCountKey("/article/"+article.getId()));
            if(clickCount==null){
                clickCount = "0";
            }
            vo.set("clickCount",clickCount);
            vo.set("article",article);
            vo.set("tags",tags);
            vos.add(vo);
        }
        model.addAttribute("vos",vos);

        ViewObject pagination = new ViewObject();
        int count = articleService.getArticleCount();
        pagination.set("current",pageId);
        pagination.set("nextPage",pageId+1);
        pagination.set("prePage",pageId-1);
        pagination.set("lastPage",count/4+1);
        model.addAttribute("pagination",pagination);

        User user = hostHolder.getUser();
        if(user == null||"admin".equals(user.getRole())){
            model.addAttribute("create",1);
        } else {
            model.addAttribute("create",0);
        }

        List<Tag> tags = tagService.getAllTag();
        model.addAttribute("tags",tags);

        ViewObject categoryCount = new ViewObject();
        for(String category : JblogUtil.categorys){
            String categoryKey = RedisKeyUntil.getCategoryKey(category);
            String num = jedisService.get(categoryKey);
            if(num!=null){
                categoryCount.set(JblogUtil.categoryMap.get(category),num);
            }else{
                categoryCount.set(JblogUtil.categoryMap.get(category),0);
            }
        }
        model.addAttribute("categoryCount",categoryCount);

        ViewObject clickCount =  new ViewObject();
        String currentPage = jedisService.get(RedisKeyUntil.getClickCountKey("/page/"+pageId));
        String sumPage = jedisService.get(RedisKeyUntil.getClickCountKey("SUM"));
        clickCount.set("currentPage",currentPage);
        clickCount.set("sumPage",sumPage);
        model.addAttribute("clickCount",clickCount);

        List<Article> hotArticles = new ArrayList<>();
        Set<String> set = jedisService.zrevrange("hotArticle",0,6);
        for(String str:set){
            int articleId = Integer.parseInt(str.split(":")[1]);
            Article article = articleService.getArticleById(articleId);
            hotArticles.add(article);
        }
        model.addAttribute("hotArticles",hotArticles);

        return "index";

    }

    @RequestMapping("/articleAdd")
    public String addArticle(@RequestParam("title")String title,@RequestParam("category")String category,
                             @RequestParam("tag")String tag,@RequestParam("describe")String describe,
                             @RequestParam("content")String content){
        Article article = new Article();
        article.setTitle(title);
        article.setCategory(category);
        article.setDescribes(describe);
        article.setCreatedDate(new Date());
        article.setCommentCount(0);
        article.setContent(JblogUtil.transfer(content));
        article.setContentRaw(content);
//        TODO 存raw
        article.setUserId(hostHolder.getUser().getId());
        int articleId = articleService.addArticle(article);

        String[] tags = tag.split(",");
        for(String tagSave:tags){
            Tag result= tagService.selectByName(tagSave);
            if(result==null){
                Tag newTag = new Tag();
                newTag.setName(tagSave);
                newTag.setCount(1);
                newTag.setUserId(hostHolder.getUser().getId());
                int tagId = tagService.addTag(newTag);
                ArticleTag articleTag = new ArticleTag();
                articleTag.setTagId(tagId);
                articleTag.setArticleId(articleId);
                articleTagRepository.save(articleTag);
            }else{
                tagService.updateCount(result.getId(),result.getCount()+1);
                ArticleTag articleTag = new ArticleTag();
                articleTag.setArticleId(articleId);
                articleTag.setTagId(result.getId());
                articleTagRepository.save(articleTag);
            }
        }
        String categoryKey = RedisKeyUntil.getCategoryKey(category);
        jedisService.incr(categoryKey);

        return "redirect:/";
    }


    @RequestMapping(value = "/category/{categoryName}",method = RequestMethod.GET)
public String category(Model model,@PathVariable("categoryName")String categoryName,@RequestParam("pageId") int pageId){
        List<Article> articles= articleService.getArticlesByCategory(categoryName,(pageId-1)*4,4);
        List<ViewObject> vos = new ArrayList<>();
        for(Article article:articles){
            ViewObject vo = new ViewObject();
            List<Tag> tags = tagService.getTagByArticleId(article.getId());
            String clickCount = jedisService.get(RedisKeyUntil.getClickCountKey("/article/"+article.getId()));
            if(clickCount==null){
                clickCount="0";
            }
            vo.set("clickCount",clickCount);
            vo.set("tags",tags);
            vo.set("article",article);
            vos.add(vo);
        }
        model.addAttribute("vos",vos);

        ViewObject pagination = new ViewObject();
        int count = articleService.getArticleCountByCategory(categoryName);
        pagination.set("current",pageId);
        pagination.set("nextPage",pageId+1);
        pagination.set("prePage",pageId-1);
        pagination.set("lastPage",count/4+1);
        model.addAttribute("pagination",pagination);

        User user = hostHolder.getUser();
        if(user==null||"admin".equals(user.getRole())){
            model.addAttribute("create",1);
        }else{
            model.addAttribute("create",0);
        }

        List<Tag> tags = tagService.getAllTag();
        model.addAttribute("tags",tags);

        model.addAttribute("category",categoryName);

        ViewObject categoryCount = new ViewObject();
        for(String category:JblogUtil.categorys){
            String categoryKey = RedisKeyUntil.getCategoryKey(category);
            String num = jedisService.get(categoryKey);
            if(num!=null){
                categoryCount.set(JblogUtil.categoryMap.get(category),num);
            }else{
                categoryCount.set(JblogUtil.categoryMap.get(category),0);
            }
        }

        model.addAttribute("categoryCount",categoryCount);

        ViewObject clickCount = new ViewObject();
        String currentPage = jedisService.get(RedisKeyUntil.getClickCountKey("/category/"+categoryName));
        String sumPage = jedisService.get(RedisKeyUntil.getClickCountKey("SUM"));
        clickCount.set("currentPage",currentPage);
        clickCount.set("sumPage",sumPage);
        model.addAttribute("clickCount",clickCount);

        List<Article> hotArticles = new ArrayList<>();
        Set<String> set = jedisService.zrevrange("hotArticles",0,6);
        for(String str:set){
            int articleId = Integer.parseInt(str.split(":")[1]);
            Article article = articleService.getArticleById(articleId);
            hotArticles.add(article);
        }
        model.addAttribute("hotArticles",hotArticles);

        return "category";

    }






    @RequestMapping(value = "/tag/{tagId}",method = RequestMethod.GET)
    public String tag(Model model, @PathVariable("tagId")int tagId, @RequestParam("pageId")int pageId){
        List<Article> articles = articleService.getArticlesByTag(tagId,(pageId-1)*4,4);
        List<ViewObject> vos = new ArrayList<>();
        for (Article article:articles){
            ViewObject vo = new ViewObject();
            List<Tag> tags = tagService.getTagByArticleId(article.getId());
            String clickCount = jedisService.get(RedisKeyUntil.getClickCountKey("/article/"+article.getId()));
            if (clickCount==null)
                clickCount = "0";
            vo.set("clickCount",clickCount);
            vo.set("article",article);
            vo.set("tags",tags);
            vos.add(vo);
        }
        model.addAttribute("vos",vos);

        ViewObject pagination = new ViewObject();
        int count = articleService.getArticleCountByTag(tagId);

        pagination.set("current",pageId);
        pagination.set("nextPage",pageId+1);
        pagination.set("prePage",pageId-1);
        pagination.set("lastPage",count/4+1);

        User user = hostHolder.getUser();
        if (user==null||"admin".equals(user.getRole())){
            model.addAttribute("create",1);
        }else {
            model.addAttribute("create",0);
        }

        List<Tag> tags = tagService.getAllTag();
        model.addAttribute("tags",tags);
        model.addAttribute("pagination",pagination);
        model.addAttribute("tagId",tagId);

        ViewObject categoryCount = new ViewObject();
        for (String category: JblogUtil.categorys){
            String categoryKey = RedisKeyUntil.getCategoryKey(category);
            String num = jedisService.get(categoryKey);
            if (num!=null)
                categoryCount.set(JblogUtil.categoryMap.get(category),num);
            else
                categoryCount.set(JblogUtil.categoryMap.get(category),0);
        }
        model.addAttribute("categoryCount",categoryCount);

        ViewObject clickCount = new ViewObject();
        String currentPage = jedisService.get(RedisKeyUntil.getClickCountKey("/tag/"+tagId));
        String sumPage = jedisService.get(RedisKeyUntil.getClickCountKey("SUM"));
        clickCount.set("currentPage",currentPage);
        clickCount.set("sumPage",sumPage);
        model.addAttribute("clickCount",clickCount);

        List<Article> hotArticles = new ArrayList<>();
        Set<String> set = jedisService.zrevrange("hotArticles",0,6);
        for (String str : set){
            int articleId = Integer.parseInt(str.split(":")[1]);
            Article article = articleService.getArticleById(articleId);
            hotArticles.add(article);
        }
        model.addAttribute("hotArticles",hotArticles);
        log.info("hotArticles:{}",hotArticles.toString());

        return "tag";
    }



    @RequestMapping("/article/{articleId}")
    public String singleArticle(Model model, @PathVariable("articleId")int articleId){
        Article article = articleService.getArticleById(articleId);
        List<Tag> tags = tagService.getTagByArticleId(article.getId());
        model.addAttribute("article",article);
        model.addAttribute("tags",tags);

        ViewObject clickCount = new ViewObject();
        String currentPage = jedisService.get(RedisKeyUntil.getClickCountKey("/article/"+articleId));
        String sumPage = jedisService.get(RedisKeyUntil.getClickCountKey("SUM"));
        clickCount.set("currentPage",currentPage);
        clickCount.set("sumPage",sumPage);
        model.addAttribute("clickCount",clickCount);

        if(hostHolder.getUser()==null)
            model.addAttribute("liked",0);
        else
            model.addAttribute("liked", likeService.getLikeStatus(hostHolder.getUser().getId(),articleId));
        model.addAttribute("likeCount",likeService.getLikeCount(articleId));
        model.addAttribute("dislikeCount",likeService.getDislikeCount(articleId));

        List<Comment> comments = commentService.getCommentByArticleId(articleId);
        List<ViewObject> vos = new ArrayList<>();
        for(Comment comment:comments){
            ViewObject vo = new ViewObject();
            vo.set("comment",comment);
            vo.set("user", userService.getUser(comment.getUserId()));
            vos.add(vo);
        }
        model.addAttribute("vos",vos);
        model.addAttribute("commentsCount", comments.size());


        String articleClickCount = jedisService.get(RedisKeyUntil.getClickCountKey("/article/"+article.getId()));
        if(articleClickCount==null){
            articleClickCount="0";
        }
        model.addAttribute("articleClickCount",articleClickCount);

        User user = hostHolder.getUser();
        if(user==null||"admin".equals(user.getRole())){
            model.addAttribute("create",1);
        }else{
            model.addAttribute("create",0);
        }

        User  author = userService.getUser(article.getUserId());
        String authorName = author.getName();
        model.addAttribute("authorName",authorName);

        return "article";
    }

}
